<template>
  <div ref="container" id="container"></div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

import sky from '@/assets/images/sky.jpeg'
import forward from '@/assets/images/forward.png'
import glass from '@/assets/images/glass.png'
import { AxesHelper, BoxGeometry, Mesh, MeshBasicMaterial, PlaneGeometry } from 'three'
import Color from 'element-plus/es/components/color-picker/src/utils/color'

export default {
  name: 'coalPole',
  data() {
    return {
      camera: null,
      scene: null,
      renderer: null,
      isUserInteracting: false,
      onPointerDownPointerX: 0,
      onPointerDownPointerY: 0,
      lon: 0,
      onPointerDownLon: 0,
      lat: 0,
      onPointerDownLat: 0,
      phi: 0,
      theta: 0,
      target: new THREE.Vector3(),
      color: [0x37a2da, 0xffdb5c, 0xfb7293, 0x67e0e3, 0x32c5e9, 0x9fe6b8, 0xff9f7f],
      texts: [
        {
          name: '内蒙煤',
          value: 323
        },
        {
          name: '龙煤',
          value: 121
        },
        {
          name: '山西煤',
          value: 56
        }
      ]
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    mouseClick(event) {
      const raycaster = new THREE.Raycaster()
      const mouse = new THREE.Vector2()
      // 将鼠标坐标归一化
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
      // 设置射线起点为鼠标位置，射线的方向为相机视角方向
      raycaster.setFromCamera(mouse, this.camera)
      // 计算射线相交
      const intersects = raycaster.intersectObjects(this.scene.children, true)
      if (intersects.length > 0) {
        // 选中物体
        const selectedObject = intersects[0].object
        this.$message.success(JSON.stringify(this.texts[selectedObject.obj]))
        selectedObject.material.forEach((m, index) => {
          if (index != 2) {
            if (m.color.getHexString() === 'ff62e2') m.color.set(0x000000)
            else m.color.set(0xff62e2)
          }
        })
      }
    },
    setSkyCute(scene) {
      const geometry = new THREE.SphereGeometry(100, 50, 10, 0, Math.PI * 2, 0, Math.PI / 2)
      const texture = new THREE.TextureLoader().load(sky)
      const material = new THREE.MeshBasicMaterial({
        map: texture,
        side: THREE.BackSide //默认前面可见，设置为背面可见即可
      })
      const mesh = new THREE.Mesh(geometry, material)
      scene.add(mesh)
    },
    getTextCanvas1(index) {
      var width = 512,
        height = 256
      var canvas = document.createElement('canvas')
      canvas.width = width
      canvas.height = height
      var ctx = canvas.getContext('2d')
      ctx.fillStyle = '#000000'
      ctx.fillRect(0, 0, width, height)
      ctx.font = 26 + 'px " bold'
      ctx.fillStyle = '#2891FF'
      ctx.fillText(`${this.texts[index].name}:${this.texts[index].value}吨`, 10, 32 * index + 30)
      return canvas
    },
    getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min //得到两个数之间的随机整数，包含最大值和最小值 公式
    },
    addCoalCute(scene, index) {
      let measure = this.getRandomInt(3, 10)
      //const nzture = new THREE.TextureLoader().load(coal)
      const cubeGeometry = new BoxGeometry(36, measure, 14)
      var materials = [
        new THREE.MeshBasicMaterial({ color: 0x000000, opacity: 0.8, transparent: true }), // right
        new THREE.MeshBasicMaterial({ color: 0x000000, opacity: 0.8, transparent: true }), // left
        new THREE.MeshBasicMaterial({ map: new THREE.CanvasTexture(this.getTextCanvas1(index)) }), // top
        new THREE.MeshBasicMaterial({ color: 0x000000, opacity: 0.8, transparent: true }), // bottom
        new THREE.MeshBasicMaterial({ color: 0x000000, opacity: 0.8, transparent: true }), // back
        new THREE.MeshBasicMaterial({ color: 0x000000, opacity: 0.8, transparent: true }) // front
      ]
      const cube = new Mesh(cubeGeometry, materials)
      cube.name = 'cute' + index
      cube.obj = index
      cube.position.set(0, measure / 2, 20 * index - 20)
      scene.add(cube)
    },
    addCoalPile(scene) {
      const nzture = new THREE.TextureLoader().load(forward)
      const dash_geometry = new THREE.CylinderGeometry(14, 15, 5, 4, 1)
      const dash_material = new THREE.MeshLambertMaterial({ map: nzture })
      const dash_mesh = new THREE.Mesh(dash_geometry, dash_material)
      scene.add(dash_mesh)
    },
    addFloor(scene, index) {
      const nzture = new THREE.TextureLoader().load(forward)
      const planeGeometry = new PlaneGeometry(38, 15)
      const meshBasicMaterial = new MeshBasicMaterial({ map: nzture })
      const plane = new Mesh(planeGeometry, meshBasicMaterial)

      plane.rotation.x = -0.5 * Math.PI
      plane.position.set(0, 0, 20 * index - 20)
      scene.add(plane)
    },
    init() {
      console.log('init')
      //1. 创建场景和摄像机
      const scene = new THREE.Scene()
      const glassture = new THREE.TextureLoader().load(glass)
      scene.background = glassture
      // 2. 创建摄像机
      // const camera = new THREE.PerspectiveCamera('视角', '指投影窗口的长宽比', '表示从距离摄像机多远的位置开始渲染', '表示距离摄像机多远的位置截止渲染 1000')
      const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000)

      camera.position.set(-30, 40, 60)
      camera.lookAt(scene.position)

      // 创建ThreeJS渲染器
      const renderer = new THREE.WebGLRenderer({ antialias: true }) // new THREE.WebGLRenderer();
      renderer.setClearColor(new Color(0xeeeeee))
      // 设置渲染器场景的大小
      renderer.setSize(window.innerWidth, window.innerHeight)
      // 把渲染器添加到我们的页面中去
      // document.body.appendChild(renderer.domElement);
      this.$refs.container.appendChild(renderer.domElement)

      const axes = new AxesHelper(20)
      axes.setColors(0xff0000, 0x008000, 0x0000ff)
      scene.add(axes)

      // const planeGeometry = new PlaneGeometry(60,82)
      // const meshBasicMaterial = new MeshBasicMaterial({map: glassture})
      // const plane = new Mesh(planeGeometry,meshBasicMaterial)
      // plane.rotation.x = -0.5*Math.PI
      // scene.add(plane)

      for (let i = 0; i < 3; i++) {
        this.addFloor(scene, i)
        this.addCoalCute(scene, i)
      }

      // this.setSkyCute(scene)
      const controls = new OrbitControls(camera, renderer.domElement)
      controls.enableDamping = true // 开启阻尼效果
      controls.rotateSpeed = 0.5 // 旋转速度
      controls.target.set(0, 0, 0) // 查看物体时的中心点

      // 动态响应窗口缩放尺寸
      window.addEventListener('resize', () => {
        // 初始化摄像机
        camera.aspect = window.innerWidth / window.innerHeight
        camera.updateProjectionMatrix() // 初始化摄像机矩阵投影
        // 初始化渲染器尺寸
        renderer.setSize(window.innerWidth, window.innerHeight)
      })

      function animate() {
        requestAnimationFrame(animate) //帧动画
        //controls.update() //更新控制器
        renderer.render(scene, camera) //渲染
      }
      animate()
      this.camera = camera
      this.scene = scene
      window.addEventListener('click', this.mouseClick, false)
    }
  }
}
</script>
<style type="text/css">
#container {
  width: 100%;
  height: 100vh;
  background: #eee;
}
</style>
